#!/usr/bin/python3
# ******************************************************************************
# Copyright (c) Huawei Technologies Co., Ltd. 2021-2021. All rights reserved.
# licensed under the Mulan PSL v2.
# You can use this software according to the terms and conditions of the Mulan PSL v2.
# You may obtain a copy of Mulan PSL v2 at:
#     http://license.coscl.org.cn/MulanPSL2
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
# PURPOSE.
# See the Mulan PSL v2 for more details.
# ******************************************************************************/
from cli.base import CveTrackingCommand
from conf import CONFIG
from core.crawler.patch import Patch
from core.download import save
from core.verification.apply import PathApply
from exception import InputError
from logger import logger


class SaveCommand(CveTrackingCommand):
    """
    Execute the command line to find the patch and save the patch file
    """

    def __init__(self):
        super(SaveCommand, self).__init__()
        self.parser = CveTrackingCommand.sub_parse.add_parser('download',
                                                              help="Perform a patch search and download the patch file")
        self._add_common_param()
        self._add_params()

    def _add_params(self):
        """
        Add the unique parameters of the command
        :return: None
        """
        self.parser.add_argument('-f', '--patch_path', metavar='patch_patch', type=str, action='store', required=False,
                                 default=CONFIG.PATCH_SAVE_PATH,
                                 help='Path to save the patch file, the default is"/opt/cve_tracking/patches"')
        self.parser.add_argument('-s', '--source_path', metavar='source_patch', type=str, action='store',
                                 required=False, default=CONFIG.SOURCE_CODE_PATH,
                                 help='Source download path, the default is: "/opt/cve_tracking/source_code"')
        self.parser.add_argument('-p', '--packing', action='store_true', required=False, default=False,
                                 help='Whether to package the verification patch')
        self.parser.add_argument('-b', '--branch', metavar='branch', type=str, action='store', required=False,
                                 default='master', help='Branch of rpm, default is "master"')

    @staticmethod
    async def run_command(args):
        """
        Search patch, save file function execution entry
        :param args: command line params
        :return: None
        """
        logger.info(f'Start to execute the download command, cve: {args.cve_num}, '
                    f'rpm: {args.rpm_name}, patch save path: {args.patch_path}')
        if not all([args.rpm_name, args.cve_num, args.patch_path]):
            raise InputError('Download command parameter error, please confirm "rpm_name"/cve_num/patch_path"')
        if args.packing and not all([args.source_path, args.branch]):
            raise InputError('Download command parameter error, please confirm "source_path/branch"')

        # find patch info
        patch = Patch(cve_num=args.cve_num, rpm_name=args.rpm_name)
        patch_detail_info = await patch.find_patches_detail()
        # download patch file
        save.save_patch(patch_details=patch_detail_info, cve=args.cve_num, path=args.patch_path)
        logger.info(f'End to execute the save file, patch save path:{args.patch_path}')

        # apply patch
        if args.packing:
            patch_apply = PathApply(rpm_name=args.rpm_name, patch_path=args.patch_path,
                                    source_path=args.source_path, branch_rpm=args.branch)
            patch_apply.packing_source()
